//
//  AppModule.m
//  iCodeMac
//
//  Created by Andrew Barry on 27/02/09.
//  Copyright 2009 Barry Computer Services. All rights reserved.
//

#import "AppModule.h"
#import "SourceEditor.h"
#import "AppStack.h"
//#import "FormLoader.h"
//#import "runtime.h"
//#import "JSVirtualMachine.h"

int gNextScriptId;

@implementation AppModule
-(id) initWithStack: (AppStack *) s withDefn: (NSDictionary *) dict {
	self = [super init];
	stack = [s retain];
	if (dict) {
		source = [[dict objectForKey:@"source"] retain];
		form = [[dict objectForKey:@"form"] retain];
	} else
		source = @"";
	JS_AddRoot(s->cx, &runObject);
	return self;
}

-(AppStack *) stack {
	return stack;
}

-(void) showCodeEditor {
	if (activeEditor == nil) {
		activeEditor = [[SourceEditor alloc] initWithModule:self];
		[activeEditor setText: source];
	}
	[activeEditor show];
}

-(void) sourceEditorClosing {
	[source release];
	source = [activeEditor text];
	[source retain];

	[activeEditor release];
	activeEditor = nil;
}

-(void) update {
	if (activeEditor) {
		[source release];
		source = [[activeEditor text] retain];
	}
}

-(void) setForm: (NSDictionary *) f {
	if (form)
		[form release];
	form = [f retain];
}

-(NSDictionary *) form {
	return form;
}

-(bool) compile {
	[scriptId release];
	scriptId = [NSString stringWithFormat:@"s%d", gNextScriptId++];
	[scriptId retain];

	const char *script = [source UTF8String];
	compiledScript = JS_CompileScript(stack->cx, JS_GetGlobalObject(stack->cx),
						script, strlen(script), [scriptId UTF8String], 1);
	if (!compiledScript)
		return false;

	if (!scriptObjectRooted) {
		JS_AddRoot(stack->cx, &scriptObject);
		scriptObjectRooted = true;
	}
	scriptObject = JS_GetScriptObject(compiledScript);
	return true;
}

-(void) runtimeErrorMessage: (NSString *) message withReport: (JSErrorReport *) report {

	[self showCodeEditor];
	
	[activeEditor runtimeErrorMessage: message withReport: report];
	if ([stack isRunning])
		[stack pause];
}

-(NSString *) scriptId {
	if (!scriptId)
		return @"";
	return scriptId;
}

-(void) runScript {
	jsval rval;
	JS_ExecuteScript(stack->cx, runObject, compiledScript, &rval);
}

-(void) runInView: (NSView *) parent {
	/*
	FormLoader *loader = [FormLoader new];
	
	runObject = newCoreObject(stack);
	
	[loader loadForm:form into:parent with:runObject forStack: stack];
	
	[[stack vm] runModule:self];
	 */
}

-(NSDictionary *) save {
	NSMutableDictionary *save = [NSMutableDictionary new];
	[save setObject:form forKey:@"form"];
	[save setObject:source forKey:@"source"];
	return save;
}

@end
